package com.netty.server;

import com.netty.pojo.RpcResponse;
import com.netty.serializer.Serializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import com.netty.pojo.RpcRequest;
import com.netty.serializer.JSONSerializer;
import com.netty.serializer.RpcDecoder;
import com.netty.serializer.RpcEncoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * @author : zhengyao3@郑瑶
 * @date : 2020/7/3 12:11
 * @Description: netty服务启动类
 */
@Component
public class StartServer implements ApplicationRunner {

    @Value("${host.name:127.0.0.1}")
    private String hostName;
    @Value("${host.port:8899}")
    private int port;
    @Autowired
    @Qualifier("serverHandler")
    private ChannelHandler serverHandler; 
    @Autowired
    @Qualifier("JSONSerializer")
    private Serializer serializer;
    
    @Override
    public void run(ApplicationArguments args) {
        System.out.println("netty服务启动中，端口号为："+port);
        try {
            NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();
                            //返回给Client端的时候使用RpcResponse
                            pipeline.addLast(new RpcEncoder(RpcResponse.class,serializer));
                            //接收的时候使用RpcRequest
                            pipeline.addLast(new RpcDecoder(RpcRequest.class,serializer));
                            pipeline.addLast(serverHandler);
                        }
                    });
            //hostName和端口可以放到通用配置文件中
            bootstrap.bind(hostName, port).sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
